<?php

/**
 * DefaultApi
 * PHP version 8.3.
 *
 * @category Class
 *
 * @author   OpenAPI Generator team
 *
 * @see     https://openapi-generator.tech
 */

/**
 * Selling Partner API for Finances.
 *
 * The Selling Partner API for Finances helps you obtain financial information relevant to a seller's business. You can obtain financial events for a given order, financial event group, or date range without having to wait until a statement period closes. You can also obtain financial event groups for a given date range.
 *
 * The version of the OpenAPI document: v0
 * Generated by: https://openapi-generator.tech
 * Generator version: 7.9.0
 */

/**
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

namespace SpApi\Api\finances\v0;

use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Psr7\MultipartStream;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\RequestOptions;
use SpApi\ApiException;
use SpApi\AuthAndAuth\RestrictedDataTokenSigner;
use SpApi\Configuration;
use SpApi\HeaderSelector;
use SpApi\Model\finances\v0\ListFinancialEventGroupsResponse;
use SpApi\Model\finances\v0\ListFinancialEventsResponse;
use SpApi\ObjectSerializer;
use Symfony\Component\RateLimiter\LimiterInterface;
use Symfony\Component\RateLimiter\RateLimiterFactory;
use Symfony\Component\RateLimiter\Storage\InMemoryStorage;

/**
 * DefaultApi Class Doc Comment.
 *
 * @category Class
 *
 * @author   OpenAPI Generator team
 *
 * @see     https://openapi-generator.tech
 */
class DefaultApi
{
    public ?LimiterInterface $listFinancialEventGroupsRateLimiter;
    public ?LimiterInterface $listFinancialEventsRateLimiter;
    public ?LimiterInterface $listFinancialEventsByGroupIdRateLimiter;
    public ?LimiterInterface $listFinancialEventsByOrderIdRateLimiter;
    protected ClientInterface $client;

    protected Configuration $config;

    protected HeaderSelector $headerSelector;

    /**
     * @var int Host index
     */
    protected int $hostIndex;

    private bool $rateLimiterEnabled;
    private InMemoryStorage $rateLimitStorage;

    /**
     * @param int $hostIndex (Optional) host index to select the list of hosts if defined in the OpenAPI spec
     */
    public function __construct(
        Configuration $config,
        ?ClientInterface $client = null,
        ?bool $rateLimiterEnabled = true,
        ?HeaderSelector $selector = null,
        int $hostIndex = 0
    ) {
        $this->config = $config;
        $this->rateLimiterEnabled = $rateLimiterEnabled;

        if ($rateLimiterEnabled) {
            $this->rateLimitStorage = new InMemoryStorage();

            $factory = new RateLimiterFactory(Configuration::getRateLimitOptions('DefaultApi-listFinancialEventGroups'), $this->rateLimitStorage);
            $this->listFinancialEventGroupsRateLimiter = $factory->create('DefaultApi-listFinancialEventGroups');
            $factory = new RateLimiterFactory(Configuration::getRateLimitOptions('DefaultApi-listFinancialEvents'), $this->rateLimitStorage);
            $this->listFinancialEventsRateLimiter = $factory->create('DefaultApi-listFinancialEvents');
            $factory = new RateLimiterFactory(Configuration::getRateLimitOptions('DefaultApi-listFinancialEventsByGroupId'), $this->rateLimitStorage);
            $this->listFinancialEventsByGroupIdRateLimiter = $factory->create('DefaultApi-listFinancialEventsByGroupId');
            $factory = new RateLimiterFactory(Configuration::getRateLimitOptions('DefaultApi-listFinancialEventsByOrderId'), $this->rateLimitStorage);
            $this->listFinancialEventsByOrderIdRateLimiter = $factory->create('DefaultApi-listFinancialEventsByOrderId');
        }

        $this->client = $client ?: new Client();
        $this->headerSelector = $selector ?: new HeaderSelector();
        $this->hostIndex = $hostIndex;
    }

    /**
     * Set the host index.
     *
     * @param int $hostIndex Host index (required)
     */
    public function setHostIndex(int $hostIndex): void
    {
        $this->hostIndex = $hostIndex;
    }

    /**
     * Get the host index.
     *
     * @return int Host index
     */
    public function getHostIndex(): int
    {
        return $this->hostIndex;
    }

    public function getConfig(): Configuration
    {
        return $this->config;
    }

    /**
     * Operation listFinancialEventGroups.
     *
     * @param null|int       $max_results_per_page
     *                                                             The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 10)
     * @param null|\DateTime $financial_event_group_started_before
     *                                                             A date used for selecting financial event groups that opened before (but not at) a specified date and time, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) format. The date-time  must be later than FinancialEventGroupStartedAfter and no later than two minutes before the request was submitted. If FinancialEventGroupStartedAfter and FinancialEventGroupStartedBefore are more than 180 days apart, no financial event groups are returned. (optional)
     * @param null|\DateTime $financial_event_group_started_after
     *                                                             A date used for selecting financial event groups that opened after (or at) a specified date and time, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) format. The date-time must be no later than two minutes before the request was submitted. (optional)
     * @param null|string    $next_token
     *                                                             A string token returned in the response of your previous request. (optional)
     * @param null|string    $restrictedDataToken                  Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function listFinancialEventGroups(
        ?int $max_results_per_page = 10,
        ?\DateTime $financial_event_group_started_before = null,
        ?\DateTime $financial_event_group_started_after = null,
        ?string $next_token = null,
        ?string $restrictedDataToken = null
    ): ListFinancialEventGroupsResponse {
        list($response) = $this->listFinancialEventGroupsWithHttpInfo($max_results_per_page, $financial_event_group_started_before, $financial_event_group_started_after, $next_token, $restrictedDataToken);

        return $response;
    }

    /**
     * Operation listFinancialEventGroupsWithHttpInfo.
     *
     * @param null|int       $max_results_per_page
     *                                                             The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 10)
     * @param null|\DateTime $financial_event_group_started_before
     *                                                             A date used for selecting financial event groups that opened before (but not at) a specified date and time, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) format. The date-time  must be later than FinancialEventGroupStartedAfter and no later than two minutes before the request was submitted. If FinancialEventGroupStartedAfter and FinancialEventGroupStartedBefore are more than 180 days apart, no financial event groups are returned. (optional)
     * @param null|\DateTime $financial_event_group_started_after
     *                                                             A date used for selecting financial event groups that opened after (or at) a specified date and time, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) format. The date-time must be no later than two minutes before the request was submitted. (optional)
     * @param null|string    $next_token
     *                                                             A string token returned in the response of your previous request. (optional)
     * @param null|string    $restrictedDataToken                  Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @return array of \SpApi\Model\finances\v0\ListFinancialEventGroupsResponse, HTTP status code, HTTP response headers (array of strings)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function listFinancialEventGroupsWithHttpInfo(
        ?int $max_results_per_page = 10,
        ?\DateTime $financial_event_group_started_before = null,
        ?\DateTime $financial_event_group_started_after = null,
        ?string $next_token = null,
        ?string $restrictedDataToken = null
    ): array {
        $request = $this->listFinancialEventGroupsRequest($max_results_per_page, $financial_event_group_started_before, $financial_event_group_started_after, $next_token);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'DefaultApi-listFinancialEventGroups');
        } else {
            $request = $this->config->sign($request);
        }

        try {
            $options = $this->createHttpClientOption();

            try {
                if ($this->rateLimiterEnabled) {
                    $this->listFinancialEventGroupsRateLimiter->consume()->ensureAccepted();
                }
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getResponse()->getBody()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }
            if ('\SpApi\Model\finances\v0\ListFinancialEventGroupsResponse' === '\SplFileObject') {
                $content = $response->getBody(); // stream goes to serializer
            } else {
                $content = (string) $response->getBody();
                if ('\SpApi\Model\finances\v0\ListFinancialEventGroupsResponse' !== 'string') {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, '\SpApi\Model\finances\v0\ListFinancialEventGroupsResponse', []),
                $response->getStatusCode(),
                $response->getHeaders(),
            ];
        } catch (ApiException $e) {
            $data = ObjectSerializer::deserialize(
                $e->getResponseBody(),
                '\SpApi\Model\finances\v0\ListFinancialEventGroupsResponse',
                $e->getResponseHeaders()
            );
            $e->setResponseObject($data);

            throw $e;
        }
    }

    /**
     * Operation listFinancialEventGroupsAsync.
     *
     * @param null|int       $max_results_per_page
     *                                                             The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 10)
     * @param null|\DateTime $financial_event_group_started_before
     *                                                             A date used for selecting financial event groups that opened before (but not at) a specified date and time, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) format. The date-time  must be later than FinancialEventGroupStartedAfter and no later than two minutes before the request was submitted. If FinancialEventGroupStartedAfter and FinancialEventGroupStartedBefore are more than 180 days apart, no financial event groups are returned. (optional)
     * @param null|\DateTime $financial_event_group_started_after
     *                                                             A date used for selecting financial event groups that opened after (or at) a specified date and time, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) format. The date-time must be no later than two minutes before the request was submitted. (optional)
     * @param null|string    $next_token
     *                                                             A string token returned in the response of your previous request. (optional)
     *
     * @throws \InvalidArgumentException
     */
    public function listFinancialEventGroupsAsync(
        ?int $max_results_per_page = 10,
        ?\DateTime $financial_event_group_started_before = null,
        ?\DateTime $financial_event_group_started_after = null,
        ?string $next_token = null
    ): PromiseInterface {
        return $this->listFinancialEventGroupsAsyncWithHttpInfo($max_results_per_page, $financial_event_group_started_before, $financial_event_group_started_after, $next_token)
            ->then(
                function ($response) {
                    return $response[0];
                }
            )
        ;
    }

    /**
     * Operation listFinancialEventGroupsAsyncWithHttpInfo.
     *
     * @param null|int       $max_results_per_page
     *                                                             The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 10)
     * @param null|\DateTime $financial_event_group_started_before
     *                                                             A date used for selecting financial event groups that opened before (but not at) a specified date and time, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) format. The date-time  must be later than FinancialEventGroupStartedAfter and no later than two minutes before the request was submitted. If FinancialEventGroupStartedAfter and FinancialEventGroupStartedBefore are more than 180 days apart, no financial event groups are returned. (optional)
     * @param null|\DateTime $financial_event_group_started_after
     *                                                             A date used for selecting financial event groups that opened after (or at) a specified date and time, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) format. The date-time must be no later than two minutes before the request was submitted. (optional)
     * @param null|string    $next_token
     *                                                             A string token returned in the response of your previous request. (optional)
     *
     * @throws \InvalidArgumentException
     */
    public function listFinancialEventGroupsAsyncWithHttpInfo(
        ?int $max_results_per_page = 10,
        ?\DateTime $financial_event_group_started_before = null,
        ?\DateTime $financial_event_group_started_after = null,
        ?string $next_token = null,
        ?string $restrictedDataToken = null
    ): PromiseInterface {
        $returnType = '\SpApi\Model\finances\v0\ListFinancialEventGroupsResponse';
        $request = $this->listFinancialEventGroupsRequest($max_results_per_page, $financial_event_group_started_before, $financial_event_group_started_after, $next_token);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'DefaultApi-listFinancialEventGroups');
        } else {
            $request = $this->config->sign($request);
        }
        if ($this->rateLimiterEnabled) {
            $this->listFinancialEventGroupsRateLimiter->consume()->ensureAccepted();
        }

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ('\SplFileObject' === $returnType) {
                        $content = $response->getBody(); // stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('string' !== $returnType) {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders(),
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();

                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            )
        ;
    }

    /**
     * Create request for operation 'listFinancialEventGroups'.
     *
     * @param null|int       $max_results_per_page
     *                                                             The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 10)
     * @param null|\DateTime $financial_event_group_started_before
     *                                                             A date used for selecting financial event groups that opened before (but not at) a specified date and time, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) format. The date-time  must be later than FinancialEventGroupStartedAfter and no later than two minutes before the request was submitted. If FinancialEventGroupStartedAfter and FinancialEventGroupStartedBefore are more than 180 days apart, no financial event groups are returned. (optional)
     * @param null|\DateTime $financial_event_group_started_after
     *                                                             A date used for selecting financial event groups that opened after (or at) a specified date and time, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) format. The date-time must be no later than two minutes before the request was submitted. (optional)
     * @param null|string    $next_token
     *                                                             A string token returned in the response of your previous request. (optional)
     *
     * @throws \InvalidArgumentException
     */
    public function listFinancialEventGroupsRequest(
        ?int $max_results_per_page = 10,
        ?\DateTime $financial_event_group_started_before = null,
        ?\DateTime $financial_event_group_started_after = null,
        ?string $next_token = null
    ): Request {
        if (null !== $max_results_per_page && $max_results_per_page > 100) {
            throw new \InvalidArgumentException('invalid value for "$max_results_per_page" when calling DefaultApi.listFinancialEventGroups, must be smaller than or equal to 100.');
        }
        if (null !== $max_results_per_page && $max_results_per_page < 1) {
            throw new \InvalidArgumentException('invalid value for "$max_results_per_page" when calling DefaultApi.listFinancialEventGroups, must be bigger than or equal to 1.');
        }

        $resourcePath = '/finances/v0/financialEventGroups';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $max_results_per_page,
            'MaxResultsPerPage', // param base name
            'integer', // openApiType
            '', // style
            false, // explode
            false, // required
            $this->config
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $financial_event_group_started_before,
            'FinancialEventGroupStartedBefore', // param base name
            'string', // openApiType
            '', // style
            false, // explode
            false, // required
            $this->config
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $financial_event_group_started_after,
            'FinancialEventGroupStartedAfter', // param base name
            'string', // openApiType
            '', // style
            false, // explode
            false, // required
            $this->config
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $next_token,
            'NextToken', // param base name
            'string', // openApiType
            '', // style
            false, // explode
            false, // required
            $this->config
        ) ?? []);

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            '',
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif ('application/json' === $headers['Content-Type']) {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams, $this->config);
            }
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = ObjectSerializer::buildQuery($queryParams, $this->config);

        return new Request(
            'GET',
            $this->config->getHost().$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation listFinancialEvents.
     *
     * @param null|int       $max_results_per_page
     *                                             The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 100)
     * @param null|\DateTime $posted_after
     *                                             A date used for selecting financial events posted after (or at) a specified time. The date-time must be no later than two minutes before the request was submitted, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. (optional)
     * @param null|\DateTime $posted_before
     *                                             A date used for selecting financial events posted before (but not at) a specified time. The date-time must be later than PostedAfter and no later than two minutes before the request was submitted, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. If PostedAfter and PostedBefore are more than 180 days apart, no financial events are returned. You must specify the PostedAfter parameter if you specify the PostedBefore parameter. Default: Now minus two minutes. (optional)
     * @param null|string    $next_token
     *                                             A string token returned in the response of your previous request. (optional)
     * @param null|string    $restrictedDataToken  Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function listFinancialEvents(
        ?int $max_results_per_page = 100,
        ?\DateTime $posted_after = null,
        ?\DateTime $posted_before = null,
        ?string $next_token = null,
        ?string $restrictedDataToken = null
    ): ListFinancialEventsResponse {
        list($response) = $this->listFinancialEventsWithHttpInfo($max_results_per_page, $posted_after, $posted_before, $next_token, $restrictedDataToken);

        return $response;
    }

    /**
     * Operation listFinancialEventsWithHttpInfo.
     *
     * @param null|int       $max_results_per_page
     *                                             The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 100)
     * @param null|\DateTime $posted_after
     *                                             A date used for selecting financial events posted after (or at) a specified time. The date-time must be no later than two minutes before the request was submitted, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. (optional)
     * @param null|\DateTime $posted_before
     *                                             A date used for selecting financial events posted before (but not at) a specified time. The date-time must be later than PostedAfter and no later than two minutes before the request was submitted, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. If PostedAfter and PostedBefore are more than 180 days apart, no financial events are returned. You must specify the PostedAfter parameter if you specify the PostedBefore parameter. Default: Now minus two minutes. (optional)
     * @param null|string    $next_token
     *                                             A string token returned in the response of your previous request. (optional)
     * @param null|string    $restrictedDataToken  Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @return array of \SpApi\Model\finances\v0\ListFinancialEventsResponse, HTTP status code, HTTP response headers (array of strings)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function listFinancialEventsWithHttpInfo(
        ?int $max_results_per_page = 100,
        ?\DateTime $posted_after = null,
        ?\DateTime $posted_before = null,
        ?string $next_token = null,
        ?string $restrictedDataToken = null
    ): array {
        $request = $this->listFinancialEventsRequest($max_results_per_page, $posted_after, $posted_before, $next_token);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'DefaultApi-listFinancialEvents');
        } else {
            $request = $this->config->sign($request);
        }

        try {
            $options = $this->createHttpClientOption();

            try {
                if ($this->rateLimiterEnabled) {
                    $this->listFinancialEventsRateLimiter->consume()->ensureAccepted();
                }
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getResponse()->getBody()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }
            if ('\SpApi\Model\finances\v0\ListFinancialEventsResponse' === '\SplFileObject') {
                $content = $response->getBody(); // stream goes to serializer
            } else {
                $content = (string) $response->getBody();
                if ('\SpApi\Model\finances\v0\ListFinancialEventsResponse' !== 'string') {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, '\SpApi\Model\finances\v0\ListFinancialEventsResponse', []),
                $response->getStatusCode(),
                $response->getHeaders(),
            ];
        } catch (ApiException $e) {
            $data = ObjectSerializer::deserialize(
                $e->getResponseBody(),
                '\SpApi\Model\finances\v0\ListFinancialEventsResponse',
                $e->getResponseHeaders()
            );
            $e->setResponseObject($data);

            throw $e;
        }
    }

    /**
     * Operation listFinancialEventsAsync.
     *
     * @param null|int       $max_results_per_page
     *                                             The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 100)
     * @param null|\DateTime $posted_after
     *                                             A date used for selecting financial events posted after (or at) a specified time. The date-time must be no later than two minutes before the request was submitted, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. (optional)
     * @param null|\DateTime $posted_before
     *                                             A date used for selecting financial events posted before (but not at) a specified time. The date-time must be later than PostedAfter and no later than two minutes before the request was submitted, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. If PostedAfter and PostedBefore are more than 180 days apart, no financial events are returned. You must specify the PostedAfter parameter if you specify the PostedBefore parameter. Default: Now minus two minutes. (optional)
     * @param null|string    $next_token
     *                                             A string token returned in the response of your previous request. (optional)
     *
     * @throws \InvalidArgumentException
     */
    public function listFinancialEventsAsync(
        ?int $max_results_per_page = 100,
        ?\DateTime $posted_after = null,
        ?\DateTime $posted_before = null,
        ?string $next_token = null
    ): PromiseInterface {
        return $this->listFinancialEventsAsyncWithHttpInfo($max_results_per_page, $posted_after, $posted_before, $next_token)
            ->then(
                function ($response) {
                    return $response[0];
                }
            )
        ;
    }

    /**
     * Operation listFinancialEventsAsyncWithHttpInfo.
     *
     * @param null|int       $max_results_per_page
     *                                             The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 100)
     * @param null|\DateTime $posted_after
     *                                             A date used for selecting financial events posted after (or at) a specified time. The date-time must be no later than two minutes before the request was submitted, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. (optional)
     * @param null|\DateTime $posted_before
     *                                             A date used for selecting financial events posted before (but not at) a specified time. The date-time must be later than PostedAfter and no later than two minutes before the request was submitted, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. If PostedAfter and PostedBefore are more than 180 days apart, no financial events are returned. You must specify the PostedAfter parameter if you specify the PostedBefore parameter. Default: Now minus two minutes. (optional)
     * @param null|string    $next_token
     *                                             A string token returned in the response of your previous request. (optional)
     *
     * @throws \InvalidArgumentException
     */
    public function listFinancialEventsAsyncWithHttpInfo(
        ?int $max_results_per_page = 100,
        ?\DateTime $posted_after = null,
        ?\DateTime $posted_before = null,
        ?string $next_token = null,
        ?string $restrictedDataToken = null
    ): PromiseInterface {
        $returnType = '\SpApi\Model\finances\v0\ListFinancialEventsResponse';
        $request = $this->listFinancialEventsRequest($max_results_per_page, $posted_after, $posted_before, $next_token);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'DefaultApi-listFinancialEvents');
        } else {
            $request = $this->config->sign($request);
        }
        if ($this->rateLimiterEnabled) {
            $this->listFinancialEventsRateLimiter->consume()->ensureAccepted();
        }

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ('\SplFileObject' === $returnType) {
                        $content = $response->getBody(); // stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('string' !== $returnType) {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders(),
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();

                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            )
        ;
    }

    /**
     * Create request for operation 'listFinancialEvents'.
     *
     * @param null|int       $max_results_per_page
     *                                             The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 100)
     * @param null|\DateTime $posted_after
     *                                             A date used for selecting financial events posted after (or at) a specified time. The date-time must be no later than two minutes before the request was submitted, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. (optional)
     * @param null|\DateTime $posted_before
     *                                             A date used for selecting financial events posted before (but not at) a specified time. The date-time must be later than PostedAfter and no later than two minutes before the request was submitted, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. If PostedAfter and PostedBefore are more than 180 days apart, no financial events are returned. You must specify the PostedAfter parameter if you specify the PostedBefore parameter. Default: Now minus two minutes. (optional)
     * @param null|string    $next_token
     *                                             A string token returned in the response of your previous request. (optional)
     *
     * @throws \InvalidArgumentException
     */
    public function listFinancialEventsRequest(
        ?int $max_results_per_page = 100,
        ?\DateTime $posted_after = null,
        ?\DateTime $posted_before = null,
        ?string $next_token = null
    ): Request {
        if (null !== $max_results_per_page && $max_results_per_page > 100) {
            throw new \InvalidArgumentException('invalid value for "$max_results_per_page" when calling DefaultApi.listFinancialEvents, must be smaller than or equal to 100.');
        }
        if (null !== $max_results_per_page && $max_results_per_page < 1) {
            throw new \InvalidArgumentException('invalid value for "$max_results_per_page" when calling DefaultApi.listFinancialEvents, must be bigger than or equal to 1.');
        }

        $resourcePath = '/finances/v0/financialEvents';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $max_results_per_page,
            'MaxResultsPerPage', // param base name
            'integer', // openApiType
            '', // style
            false, // explode
            false, // required
            $this->config
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $posted_after,
            'PostedAfter', // param base name
            'string', // openApiType
            '', // style
            false, // explode
            false, // required
            $this->config
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $posted_before,
            'PostedBefore', // param base name
            'string', // openApiType
            '', // style
            false, // explode
            false, // required
            $this->config
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $next_token,
            'NextToken', // param base name
            'string', // openApiType
            '', // style
            false, // explode
            false, // required
            $this->config
        ) ?? []);

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            '',
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif ('application/json' === $headers['Content-Type']) {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams, $this->config);
            }
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = ObjectSerializer::buildQuery($queryParams, $this->config);

        return new Request(
            'GET',
            $this->config->getHost().$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation listFinancialEventsByGroupId.
     *
     * @param string         $event_group_id
     *                                             The identifier of the financial event group to which the events belong. (required)
     * @param null|int       $max_results_per_page
     *                                             The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 100)
     * @param null|\DateTime $posted_after
     *                                             A date used for selecting financial events posted after (or at) a specified time. The date-time **must** be more than two minutes before the time of the request, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. (optional)
     * @param null|\DateTime $posted_before
     *                                             A date used for selecting financial events posted before (but not at) a specified time. The date-time must be later than &#x60;PostedAfter&#x60; and no later than two minutes before the request was submitted, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. If &#x60;PostedAfter&#x60; and &#x60;PostedBefore&#x60; are more than 180 days apart, no financial events are returned. You must specify the &#x60;PostedAfter&#x60; parameter if you specify the &#x60;PostedBefore&#x60; parameter. Default: Now minus two minutes. (optional)
     * @param null|string    $next_token
     *                                             A string token returned in the response of your previous request. (optional)
     * @param null|string    $restrictedDataToken  Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function listFinancialEventsByGroupId(
        string $event_group_id,
        ?int $max_results_per_page = 100,
        ?\DateTime $posted_after = null,
        ?\DateTime $posted_before = null,
        ?string $next_token = null,
        ?string $restrictedDataToken = null
    ): ListFinancialEventsResponse {
        list($response) = $this->listFinancialEventsByGroupIdWithHttpInfo($event_group_id, $max_results_per_page, $posted_after, $posted_before, $next_token, $restrictedDataToken);

        return $response;
    }

    /**
     * Operation listFinancialEventsByGroupIdWithHttpInfo.
     *
     * @param string         $event_group_id
     *                                             The identifier of the financial event group to which the events belong. (required)
     * @param null|int       $max_results_per_page
     *                                             The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 100)
     * @param null|\DateTime $posted_after
     *                                             A date used for selecting financial events posted after (or at) a specified time. The date-time **must** be more than two minutes before the time of the request, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. (optional)
     * @param null|\DateTime $posted_before
     *                                             A date used for selecting financial events posted before (but not at) a specified time. The date-time must be later than &#x60;PostedAfter&#x60; and no later than two minutes before the request was submitted, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. If &#x60;PostedAfter&#x60; and &#x60;PostedBefore&#x60; are more than 180 days apart, no financial events are returned. You must specify the &#x60;PostedAfter&#x60; parameter if you specify the &#x60;PostedBefore&#x60; parameter. Default: Now minus two minutes. (optional)
     * @param null|string    $next_token
     *                                             A string token returned in the response of your previous request. (optional)
     * @param null|string    $restrictedDataToken  Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @return array of \SpApi\Model\finances\v0\ListFinancialEventsResponse, HTTP status code, HTTP response headers (array of strings)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function listFinancialEventsByGroupIdWithHttpInfo(
        string $event_group_id,
        ?int $max_results_per_page = 100,
        ?\DateTime $posted_after = null,
        ?\DateTime $posted_before = null,
        ?string $next_token = null,
        ?string $restrictedDataToken = null
    ): array {
        $request = $this->listFinancialEventsByGroupIdRequest($event_group_id, $max_results_per_page, $posted_after, $posted_before, $next_token);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'DefaultApi-listFinancialEventsByGroupId');
        } else {
            $request = $this->config->sign($request);
        }

        try {
            $options = $this->createHttpClientOption();

            try {
                if ($this->rateLimiterEnabled) {
                    $this->listFinancialEventsByGroupIdRateLimiter->consume()->ensureAccepted();
                }
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getResponse()->getBody()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }
            if ('\SpApi\Model\finances\v0\ListFinancialEventsResponse' === '\SplFileObject') {
                $content = $response->getBody(); // stream goes to serializer
            } else {
                $content = (string) $response->getBody();
                if ('\SpApi\Model\finances\v0\ListFinancialEventsResponse' !== 'string') {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, '\SpApi\Model\finances\v0\ListFinancialEventsResponse', []),
                $response->getStatusCode(),
                $response->getHeaders(),
            ];
        } catch (ApiException $e) {
            $data = ObjectSerializer::deserialize(
                $e->getResponseBody(),
                '\SpApi\Model\finances\v0\ListFinancialEventsResponse',
                $e->getResponseHeaders()
            );
            $e->setResponseObject($data);

            throw $e;
        }
    }

    /**
     * Operation listFinancialEventsByGroupIdAsync.
     *
     * @param string         $event_group_id
     *                                             The identifier of the financial event group to which the events belong. (required)
     * @param null|int       $max_results_per_page
     *                                             The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 100)
     * @param null|\DateTime $posted_after
     *                                             A date used for selecting financial events posted after (or at) a specified time. The date-time **must** be more than two minutes before the time of the request, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. (optional)
     * @param null|\DateTime $posted_before
     *                                             A date used for selecting financial events posted before (but not at) a specified time. The date-time must be later than &#x60;PostedAfter&#x60; and no later than two minutes before the request was submitted, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. If &#x60;PostedAfter&#x60; and &#x60;PostedBefore&#x60; are more than 180 days apart, no financial events are returned. You must specify the &#x60;PostedAfter&#x60; parameter if you specify the &#x60;PostedBefore&#x60; parameter. Default: Now minus two minutes. (optional)
     * @param null|string    $next_token
     *                                             A string token returned in the response of your previous request. (optional)
     *
     * @throws \InvalidArgumentException
     */
    public function listFinancialEventsByGroupIdAsync(
        string $event_group_id,
        ?int $max_results_per_page = 100,
        ?\DateTime $posted_after = null,
        ?\DateTime $posted_before = null,
        ?string $next_token = null
    ): PromiseInterface {
        return $this->listFinancialEventsByGroupIdAsyncWithHttpInfo($event_group_id, $max_results_per_page, $posted_after, $posted_before, $next_token)
            ->then(
                function ($response) {
                    return $response[0];
                }
            )
        ;
    }

    /**
     * Operation listFinancialEventsByGroupIdAsyncWithHttpInfo.
     *
     * @param string         $event_group_id
     *                                             The identifier of the financial event group to which the events belong. (required)
     * @param null|int       $max_results_per_page
     *                                             The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 100)
     * @param null|\DateTime $posted_after
     *                                             A date used for selecting financial events posted after (or at) a specified time. The date-time **must** be more than two minutes before the time of the request, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. (optional)
     * @param null|\DateTime $posted_before
     *                                             A date used for selecting financial events posted before (but not at) a specified time. The date-time must be later than &#x60;PostedAfter&#x60; and no later than two minutes before the request was submitted, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. If &#x60;PostedAfter&#x60; and &#x60;PostedBefore&#x60; are more than 180 days apart, no financial events are returned. You must specify the &#x60;PostedAfter&#x60; parameter if you specify the &#x60;PostedBefore&#x60; parameter. Default: Now minus two minutes. (optional)
     * @param null|string    $next_token
     *                                             A string token returned in the response of your previous request. (optional)
     *
     * @throws \InvalidArgumentException
     */
    public function listFinancialEventsByGroupIdAsyncWithHttpInfo(
        string $event_group_id,
        ?int $max_results_per_page = 100,
        ?\DateTime $posted_after = null,
        ?\DateTime $posted_before = null,
        ?string $next_token = null,
        ?string $restrictedDataToken = null
    ): PromiseInterface {
        $returnType = '\SpApi\Model\finances\v0\ListFinancialEventsResponse';
        $request = $this->listFinancialEventsByGroupIdRequest($event_group_id, $max_results_per_page, $posted_after, $posted_before, $next_token);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'DefaultApi-listFinancialEventsByGroupId');
        } else {
            $request = $this->config->sign($request);
        }
        if ($this->rateLimiterEnabled) {
            $this->listFinancialEventsByGroupIdRateLimiter->consume()->ensureAccepted();
        }

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ('\SplFileObject' === $returnType) {
                        $content = $response->getBody(); // stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('string' !== $returnType) {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders(),
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();

                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            )
        ;
    }

    /**
     * Create request for operation 'listFinancialEventsByGroupId'.
     *
     * @param string         $event_group_id
     *                                             The identifier of the financial event group to which the events belong. (required)
     * @param null|int       $max_results_per_page
     *                                             The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 100)
     * @param null|\DateTime $posted_after
     *                                             A date used for selecting financial events posted after (or at) a specified time. The date-time **must** be more than two minutes before the time of the request, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. (optional)
     * @param null|\DateTime $posted_before
     *                                             A date used for selecting financial events posted before (but not at) a specified time. The date-time must be later than &#x60;PostedAfter&#x60; and no later than two minutes before the request was submitted, in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date time format. If &#x60;PostedAfter&#x60; and &#x60;PostedBefore&#x60; are more than 180 days apart, no financial events are returned. You must specify the &#x60;PostedAfter&#x60; parameter if you specify the &#x60;PostedBefore&#x60; parameter. Default: Now minus two minutes. (optional)
     * @param null|string    $next_token
     *                                             A string token returned in the response of your previous request. (optional)
     *
     * @throws \InvalidArgumentException
     */
    public function listFinancialEventsByGroupIdRequest(
        string $event_group_id,
        ?int $max_results_per_page = 100,
        ?\DateTime $posted_after = null,
        ?\DateTime $posted_before = null,
        ?string $next_token = null
    ): Request {
        // verify the required parameter 'event_group_id' is set
        if (null === $event_group_id || (is_array($event_group_id) && 0 === count($event_group_id))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $event_group_id when calling listFinancialEventsByGroupId'
            );
        }
        if (null !== $max_results_per_page && $max_results_per_page > 100) {
            throw new \InvalidArgumentException('invalid value for "$max_results_per_page" when calling DefaultApi.listFinancialEventsByGroupId, must be smaller than or equal to 100.');
        }
        if (null !== $max_results_per_page && $max_results_per_page < 1) {
            throw new \InvalidArgumentException('invalid value for "$max_results_per_page" when calling DefaultApi.listFinancialEventsByGroupId, must be bigger than or equal to 1.');
        }

        $resourcePath = '/finances/v0/financialEventGroups/{eventGroupId}/financialEvents';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $max_results_per_page,
            'MaxResultsPerPage', // param base name
            'integer', // openApiType
            '', // style
            false, // explode
            false, // required
            $this->config
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $posted_after,
            'PostedAfter', // param base name
            'string', // openApiType
            '', // style
            false, // explode
            false, // required
            $this->config
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $posted_before,
            'PostedBefore', // param base name
            'string', // openApiType
            '', // style
            false, // explode
            false, // required
            $this->config
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $next_token,
            'NextToken', // param base name
            'string', // openApiType
            '', // style
            false, // explode
            false, // required
            $this->config
        ) ?? []);

        // path params
        if (null !== $event_group_id) {
            $resourcePath = str_replace(
                '{eventGroupId}',
                ObjectSerializer::toPathValue($event_group_id),
                $resourcePath
            );
        }

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            '',
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif ('application/json' === $headers['Content-Type']) {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams, $this->config);
            }
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = ObjectSerializer::buildQuery($queryParams, $this->config);

        return new Request(
            'GET',
            $this->config->getHost().$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation listFinancialEventsByOrderId.
     *
     * @param string      $order_id
     *                                          An Amazon-defined order identifier, in 3-7-7 format. (required)
     * @param null|int    $max_results_per_page
     *                                          The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 100)
     * @param null|string $next_token
     *                                          A string token returned in the response of your previous request. (optional)
     * @param null|string $restrictedDataToken  Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function listFinancialEventsByOrderId(
        string $order_id,
        ?int $max_results_per_page = 100,
        ?string $next_token = null,
        ?string $restrictedDataToken = null
    ): ListFinancialEventsResponse {
        list($response) = $this->listFinancialEventsByOrderIdWithHttpInfo($order_id, $max_results_per_page, $next_token, $restrictedDataToken);

        return $response;
    }

    /**
     * Operation listFinancialEventsByOrderIdWithHttpInfo.
     *
     * @param string      $order_id
     *                                          An Amazon-defined order identifier, in 3-7-7 format. (required)
     * @param null|int    $max_results_per_page
     *                                          The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 100)
     * @param null|string $next_token
     *                                          A string token returned in the response of your previous request. (optional)
     * @param null|string $restrictedDataToken  Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @return array of \SpApi\Model\finances\v0\ListFinancialEventsResponse, HTTP status code, HTTP response headers (array of strings)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function listFinancialEventsByOrderIdWithHttpInfo(
        string $order_id,
        ?int $max_results_per_page = 100,
        ?string $next_token = null,
        ?string $restrictedDataToken = null
    ): array {
        $request = $this->listFinancialEventsByOrderIdRequest($order_id, $max_results_per_page, $next_token);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'DefaultApi-listFinancialEventsByOrderId');
        } else {
            $request = $this->config->sign($request);
        }

        try {
            $options = $this->createHttpClientOption();

            try {
                if ($this->rateLimiterEnabled) {
                    $this->listFinancialEventsByOrderIdRateLimiter->consume()->ensureAccepted();
                }
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getResponse()->getBody()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }
            if ('\SpApi\Model\finances\v0\ListFinancialEventsResponse' === '\SplFileObject') {
                $content = $response->getBody(); // stream goes to serializer
            } else {
                $content = (string) $response->getBody();
                if ('\SpApi\Model\finances\v0\ListFinancialEventsResponse' !== 'string') {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, '\SpApi\Model\finances\v0\ListFinancialEventsResponse', []),
                $response->getStatusCode(),
                $response->getHeaders(),
            ];
        } catch (ApiException $e) {
            $data = ObjectSerializer::deserialize(
                $e->getResponseBody(),
                '\SpApi\Model\finances\v0\ListFinancialEventsResponse',
                $e->getResponseHeaders()
            );
            $e->setResponseObject($data);

            throw $e;
        }
    }

    /**
     * Operation listFinancialEventsByOrderIdAsync.
     *
     * @param string      $order_id
     *                                          An Amazon-defined order identifier, in 3-7-7 format. (required)
     * @param null|int    $max_results_per_page
     *                                          The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 100)
     * @param null|string $next_token
     *                                          A string token returned in the response of your previous request. (optional)
     *
     * @throws \InvalidArgumentException
     */
    public function listFinancialEventsByOrderIdAsync(
        string $order_id,
        ?int $max_results_per_page = 100,
        ?string $next_token = null
    ): PromiseInterface {
        return $this->listFinancialEventsByOrderIdAsyncWithHttpInfo($order_id, $max_results_per_page, $next_token)
            ->then(
                function ($response) {
                    return $response[0];
                }
            )
        ;
    }

    /**
     * Operation listFinancialEventsByOrderIdAsyncWithHttpInfo.
     *
     * @param string      $order_id
     *                                          An Amazon-defined order identifier, in 3-7-7 format. (required)
     * @param null|int    $max_results_per_page
     *                                          The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 100)
     * @param null|string $next_token
     *                                          A string token returned in the response of your previous request. (optional)
     *
     * @throws \InvalidArgumentException
     */
    public function listFinancialEventsByOrderIdAsyncWithHttpInfo(
        string $order_id,
        ?int $max_results_per_page = 100,
        ?string $next_token = null,
        ?string $restrictedDataToken = null
    ): PromiseInterface {
        $returnType = '\SpApi\Model\finances\v0\ListFinancialEventsResponse';
        $request = $this->listFinancialEventsByOrderIdRequest($order_id, $max_results_per_page, $next_token);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'DefaultApi-listFinancialEventsByOrderId');
        } else {
            $request = $this->config->sign($request);
        }
        if ($this->rateLimiterEnabled) {
            $this->listFinancialEventsByOrderIdRateLimiter->consume()->ensureAccepted();
        }

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ('\SplFileObject' === $returnType) {
                        $content = $response->getBody(); // stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('string' !== $returnType) {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders(),
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();

                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            )
        ;
    }

    /**
     * Create request for operation 'listFinancialEventsByOrderId'.
     *
     * @param string      $order_id
     *                                          An Amazon-defined order identifier, in 3-7-7 format. (required)
     * @param null|int    $max_results_per_page
     *                                          The maximum number of results to return per page. If the response exceeds the maximum number of transactions or 10 MB, the API responds with &#39;InvalidInput&#39;. (optional, default to 100)
     * @param null|string $next_token
     *                                          A string token returned in the response of your previous request. (optional)
     *
     * @throws \InvalidArgumentException
     */
    public function listFinancialEventsByOrderIdRequest(
        string $order_id,
        ?int $max_results_per_page = 100,
        ?string $next_token = null
    ): Request {
        // verify the required parameter 'order_id' is set
        if (null === $order_id || (is_array($order_id) && 0 === count($order_id))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $order_id when calling listFinancialEventsByOrderId'
            );
        }
        if (null !== $max_results_per_page && $max_results_per_page > 100) {
            throw new \InvalidArgumentException('invalid value for "$max_results_per_page" when calling DefaultApi.listFinancialEventsByOrderId, must be smaller than or equal to 100.');
        }
        if (null !== $max_results_per_page && $max_results_per_page < 1) {
            throw new \InvalidArgumentException('invalid value for "$max_results_per_page" when calling DefaultApi.listFinancialEventsByOrderId, must be bigger than or equal to 1.');
        }

        $resourcePath = '/finances/v0/orders/{orderId}/financialEvents';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $max_results_per_page,
            'MaxResultsPerPage', // param base name
            'integer', // openApiType
            '', // style
            false, // explode
            false, // required
            $this->config
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $next_token,
            'NextToken', // param base name
            'string', // openApiType
            '', // style
            false, // explode
            false, // required
            $this->config
        ) ?? []);

        // path params
        if (null !== $order_id) {
            $resourcePath = str_replace(
                '{orderId}',
                ObjectSerializer::toPathValue($order_id),
                $resourcePath
            );
        }

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            '',
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif ('application/json' === $headers['Content-Type']) {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams, $this->config);
            }
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = ObjectSerializer::buildQuery($queryParams, $this->config);

        return new Request(
            'GET',
            $this->config->getHost().$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Create http client option.
     *
     * @return array of http client options
     *
     * @throws \RuntimeException on file opening failure
     */
    protected function createHttpClientOption(): array
    {
        $options = [];
        if ($this->config->getDebug()) {
            $options[RequestOptions::DEBUG] = fopen($this->config->getDebugFile(), 'a');
            if (!$options[RequestOptions::DEBUG]) {
                throw new \RuntimeException('Failed to open the debug file: '.$this->config->getDebugFile());
            }
        }

        return $options;
    }
}
